Skip to content

feat(widget): add collapsible split view for responsive dashboard#548

Open
sandy-yield wants to merge 3 commits into
mainfrom
feat/responsive-dashboard-split-view
Open

feat(widget): add collapsible split view for responsive dashboard#548
sandy-yield wants to merge 3 commits into
mainfrom
feat/responsive-dashboard-split-view

Conversation

@sandy-yield

@sandy-yield sandy-yield commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Collapse the dashboard's two-column layout into a single panel at/below 800px, with an edge toggle bar (sitting on the hidden side) that swaps between panels while keeping both mounted to preserve state. Adds a useMediaQuery hook and shared split breakpoint helpers, scopes the column max-widths to desktop, and animates the panel transition.

Screen.Recording.2026-06-25.at.1.02.31.AM.mov

Summary by CodeRabbit

  • New Features

    • Added a responsive split-view layout to dashboard screens, letting users switch between primary and secondary panels on smaller screens.
    • Added localized labels for the new split-view controls in English and French.
    • Improved media-query handling for more responsive dashboard layouts.
  • Bug Fixes

    • Updated dashboard sizing so content stays centered and scales better across screen sizes.
    • Improved accessibility and interaction behavior for panel switching.

Collapse the dashboard's two-column layout into a single panel at/below
800px, with an edge toggle bar (sitting on the hidden side) that swaps
between panels while keeping both mounted to preserve state. Adds a
useMediaQuery hook and shared split breakpoint helpers, scopes the
column max-widths to desktop, and animates the panel transition.
@changeset-bot

changeset-bot Bot commented Jun 24, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: a498321

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 46802d55-29d5-4aed-a428-7a10b61eac25

📥 Commits

Reviewing files that changed from the base of the PR and between 13c5cfd and a498321.

📒 Files selected for processing (4)
  • packages/widget/src/App.tsx
  • packages/widget/src/pages-dashboard/common/components/tab-page-container.tsx
  • packages/widget/src/styles/theme/global.css.ts
  • packages/widget/src/styles/theme/ids.ts
💤 Files with no reviewable changes (1)
  • packages/widget/src/pages-dashboard/common/components/tab-page-container.tsx
✅ Files skipped from review due to trivial changes (2)
  • packages/widget/src/App.tsx
  • packages/widget/src/styles/theme/ids.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/widget/src/styles/theme/global.css.ts

📝 Walkthrough

Walkthrough

Adds a responsive dashboard split-view layout with a shared media-query hook, a SplitView component, updated dashboard shell styling, and overview/position-details pages that render split panes with translated labels and responsive width rules.

Changes

Dashboard split-view layout

Layer / File(s) Summary
Media-query primitives
packages/widget/src/styles/tokens/breakpoints.ts, packages/widget/src/hooks/use-media-query.ts
Adds split-view breakpoint media queries and numeric pixel support, and the media-query hook reads matchMedia safely in SSR.
SplitView component
packages/widget/src/pages-dashboard/common/components/split-view/index.tsx, packages/widget/src/pages-dashboard/common/components/split-view/styles.css.ts
SplitView renders primary and secondary panes, collapses to one side under the split breakpoint, and adds the toggle bar, animations, and bar styling.
Dashboard shell layout
packages/widget/src/App.tsx, packages/widget/src/styles/theme/ids.ts, packages/widget/src/styles/theme/global.css.ts, packages/widget/src/pages-dashboard/common/components/styles.css.ts, packages/widget/src/pages-dashboard/common/components/tab-page-container.tsx
The dashboard root adds a layout attribute and selector, the shared wrapper becomes responsive, and the tab-page container export is removed.
Overview split view
packages/widget/src/pages-dashboard/overview/index.tsx, packages/widget/src/pages-dashboard/overview/styles.css.ts, packages/widget/src/translation/English/translations.json, packages/widget/src/translation/French/translations.json
OverviewPage renders SplitView with translated bar labels, places the outlet in the primary pane and EarnDetails in the secondary pane, and gates its max-width under splitExpandedMediaQuery.
Position details split view
packages/widget/src/pages-dashboard/position-details/index.tsx, packages/widget/src/pages-dashboard/position-details/styles.css.ts
PositionDetailsPageComponent renders SplitView, repositions the breadcrumb, actions, and details content into split panes, and ties page max-width rules to splitExpandedMediaQuery.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant SplitView
  participant useMediaQuery
  participant "window.matchMedia" as MatchMedia
  participant MediaQueryList

  User->>SplitView: render page content
  SplitView->>useMediaQuery: useMediaQuery(splitCollapsedMediaQuery)
  useMediaQuery->>MatchMedia: matchMedia(query)
  MatchMedia-->>useMediaQuery: MediaQueryList
  useMediaQuery->>MediaQueryList: addEventListener("change", ...)
  User->>SplitView: click collapsed bar
  SplitView->>SplitView: setActiveSide(...)
  MediaQueryList-->>useMediaQuery: change event
  SplitView-->>User: update visible pane
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested reviewers

  • Philippoes
  • dnehl
  • jdomingos

Poem

🐰 I hopped through panes from left to right,
With split bars glowing soft and bright.
A query blinked, “Collapse, expand!”
I tapped the bar with paw and hand.
Then carrot crumbs lined up just fine.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the change, but it does not follow the required Added/Changed template sections. Rewrite it with ## Added and ## Changed sections, briefly covering the new feature and the modifications made.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly names the new collapsible split view and its responsive dashboard scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/responsive-dashboard-split-view

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@aws-amplify-eu-central-1

Copy link
Copy Markdown

This pull request is automatically being deployed by Amplify Hosting (learn more).

Access this pull request here: https://pr-548.df4xyoi0xyeak.amplifyapp.com

@aws-amplify-eu-central-1

Copy link
Copy Markdown

This pull request is automatically being deployed by Amplify Hosting (learn more).

Access this pull request here: https://pr-548.d2ribjy8evqo6h.amplifyapp.com

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/widget/src/pages-dashboard/common/components/tab-page-container.tsx (1)

1-14: 📐 Maintainability & Code Quality | 🟡 Minor

Delete packages/widget/src/pages-dashboard/common/components/tab-page-container.tsx. The entire TabPageContainer implementation is commented out, and there are no remaining references to TabPageContainer or tab-page-container elsewhere in the component tree. Remove the dead file instead of keeping commented-out code.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/widget/src/pages-dashboard/common/components/tab-page-container.tsx`
around lines 1 - 14, Remove the dead TabPageContainer module entirely: the
entire implementation in TabPageContainer is commented out and there are no
remaining references to TabPageContainer or tab-page-container. Delete the file
rather than leaving a commented stub, and ensure any imports or exports that may
still reference TabPageContainer are cleaned up.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/widget/src/pages-dashboard/common/components/split-view/index.tsx`:
- Around line 28-30: The pane-presence check in split-view is using a falsy test
that can treat valid ReactNode values like 0 or "" as missing. Update the
conditional in the SplitView render logic to use explicit null/undefined checks
for primary and secondary instead of !primary or !secondary, and keep the
fallback Box rendering behavior the same when one pane is actually absent.

In `@packages/widget/src/pages-dashboard/common/components/styles.css.ts`:
- Around line 14-16: Remove the conflicting minWidth rule from the dashboard
styles so the maxWidth cap can work correctly. Update the style object in the
shared dashboard component styles to keep width on 100% and maxWidth at 1000px,
but drop minWidth from the same declaration. Use the existing styles definition
in the component stylesheet to locate and adjust this layout rule.

In `@packages/widget/src/styles/tokens/breakpoints.ts`:
- Around line 24-25: The split/collapse breakpoint logic in
splitExpandedMediaQuery creates a fractional no-match gap between the collapsed
and expanded queries. Update the breakpoint definitions around
SPLIT_COLLAPSE_BREAKPOINT and minMediaQuery so the collapsed and expanded ranges
meet without leaving any unmatched widths, using the existing breakpoint symbols
in breakpoints.ts.

---

Outside diff comments:
In
`@packages/widget/src/pages-dashboard/common/components/tab-page-container.tsx`:
- Around line 1-14: Remove the dead TabPageContainer module entirely: the entire
implementation in TabPageContainer is commented out and there are no remaining
references to TabPageContainer or tab-page-container. Delete the file rather
than leaving a commented stub, and ensure any imports or exports that may still
reference TabPageContainer are cleaned up.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3c4c458c-a606-474e-963e-d6623f9ba1b2

📥 Commits

Reviewing files that changed from the base of the PR and between 2de9c9f and 13c5cfd.

📒 Files selected for processing (14)
  • packages/widget/src/hooks/use-media-query.ts
  • packages/widget/src/pages-dashboard/common/components/split-view/index.tsx
  • packages/widget/src/pages-dashboard/common/components/split-view/styles.css.ts
  • packages/widget/src/pages-dashboard/common/components/styles.css.ts
  • packages/widget/src/pages-dashboard/common/components/tab-page-container.tsx
  • packages/widget/src/pages-dashboard/overview/index.tsx
  • packages/widget/src/pages-dashboard/overview/styles.css.ts
  • packages/widget/src/pages-dashboard/position-details/index.tsx
  • packages/widget/src/pages-dashboard/position-details/styles.css.ts
  • packages/widget/src/style.css.ts
  • packages/widget/src/styles/theme/global.css.ts
  • packages/widget/src/styles/tokens/breakpoints.ts
  • packages/widget/src/translation/English/translations.json
  • packages/widget/src/translation/French/translations.json

Comment on lines +28 to +30
if (!primary || !secondary) {
return <Box className={styles.container}>{primary || secondary}</Box>;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use null checks instead of falsy checks for pane presence.

!primary || !secondary can misclassify valid ReactNode values like 0 or "" as missing.

Suggested fix
-  if (!primary || !secondary) {
+  if (primary == null || secondary == null) {
     return <Box className={styles.container}>{primary || secondary}</Box>;
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/widget/src/pages-dashboard/common/components/split-view/index.tsx`
around lines 28 - 30, The pane-presence check in split-view is using a falsy
test that can treat valid ReactNode values like 0 or "" as missing. Update the
conditional in the SplitView render logic to use explicit null/undefined checks
for primary and secondary instead of !primary or !secondary, and keep the
fallback Box rendering behavior the same when one pane is actually absent.

Comment on lines +14 to +16
maxWidth: "1000px",
width: "100%",
minWidth: "100%",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -nP '\bwrapper\s*\(' packages/widget/src -C3
rg -nP 'minWidth' packages/widget/src/pages-dashboard/common/components/styles.css.ts -C2

Repository: stakekit/widget

Length of output: 251


🏁 Script executed:

#!/bin/bash
set -euo pipefail

git ls-files 'packages/widget/src/pages-dashboard/common/components/*' 'packages/widget/src/pages-dashboard/**/styles.css.ts' 'packages/widget/src/**/styles.css.ts' | sed -n '1,200p'

echo '--- styles.css.ts outline ---'
ast-grep outline packages/widget/src/pages-dashboard/common/components/styles.css.ts --view expanded || true

echo '--- surrounding file ---'
cat -n packages/widget/src/pages-dashboard/common/components/styles.css.ts | sed -n '1,120p'

echo '--- search for wrapper/appContainer/dashboard variant ---'
rg -n 'appContainer|wrapper|dashboard variant|minWidth: "100%"|maxWidth: "1000px"' packages/widget/src -C 3

Repository: stakekit/widget

Length of output: 29018


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- packages/widget/src/style.css.ts ---'
cat -n packages/widget/src/style.css.ts | sed -n '1,140p'

echo '--- packages/widget/src/pages-dashboard/common/components/wrapper.tsx ---'
cat -n packages/widget/src/pages-dashboard/common/components/wrapper.tsx | sed -n '1,120p'

Repository: stakekit/widget

Length of output: 3150


Remove minWidth: "100%"

minWidth: "100%" prevents the new maxWidth: "1000px" cap from taking effect on wider dashboard layouts. width: "100%" is enough here.

🐛 Proposed fix
       maxWidth: "1000px",
       width: "100%",
-      minWidth: "100%",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
maxWidth: "1000px",
width: "100%",
minWidth: "100%",
maxWidth: "1000px",
width: "100%",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/widget/src/pages-dashboard/common/components/styles.css.ts` around
lines 14 - 16, Remove the conflicting minWidth rule from the dashboard styles so
the maxWidth cap can work correctly. Update the style object in the shared
dashboard component styles to keep width on 100% and maxWidth at 1000px, but
drop minWidth from the same declaration. Use the existing styles definition in
the component stylesheet to locate and adjust this layout rule.

Comment on lines +24 to +25
export const splitExpandedMediaQuery = minMediaQuery(
SPLIT_COLLAPSE_BREAKPOINT + 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Avoid a no-match gap between collapsed and expanded media queries.

Using min-width: 801px leaves widths between 800px and 801px unmatched (fractional CSS pixels), which can cause inconsistent responsive behavior.

Suggested fix
 export const splitExpandedMediaQuery = minMediaQuery(
-  SPLIT_COLLAPSE_BREAKPOINT + 1
+  SPLIT_COLLAPSE_BREAKPOINT
 );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const splitExpandedMediaQuery = minMediaQuery(
SPLIT_COLLAPSE_BREAKPOINT + 1
export const splitExpandedMediaQuery = minMediaQuery(
SPLIT_COLLAPSE_BREAKPOINT
);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/widget/src/styles/tokens/breakpoints.ts` around lines 24 - 25, The
split/collapse breakpoint logic in splitExpandedMediaQuery creates a fractional
no-match gap between the collapsed and expanded queries. Update the breakpoint
definitions around SPLIT_COLLAPSE_BREAKPOINT and minMediaQuery so the collapsed
and expanded ranges meet without leaving any unmatched widths, using the
existing breakpoint symbols in breakpoints.ts.

@dnehl dnehl left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@petar-omni — could you take a careful look at this one based on what we discussed last week re: widget-pro? Your point then was that the responsive layout isn't really something we need to own — it's more of a showcase, and integrators would normally add their own breakpoints / widget variants and configure it how they like. The split-view itself is fine as a demo, but one thing in here goes beyond that and I'd like your read before we merge:
Global style changes that hit every embed, not just the dashboard showcase:

  • padding: 16px added to appContainer base (style.css.ts) — this applies to the standalone widget variant too (App.tsx), and there was no padding before. So every existing customer integration gains 16px of padding → visible shift.
  • global.css.ts adds maxWidth: 1000px + margin: auto on the root selector — forces centering/capping on all embeds.
  • wrapper width 1000px → 100% / minWidth 100%.

My main concern: existing integrations should look identical after this, and these change the default appearance for everyone without opt-in.

Can we pull these out of the showcase PR (or explicitly justify them)?

Restrict the responsive split-view layout styles to dashboard mode so
standalone widget integrations render identically to before. Move the
root max-width/centering out of the global root selector into a
dashboard-only rule gated by a data-sk-layout marker, and drop the
appContainer base padding.
@sandy-yield sandy-yield requested a review from dnehl June 25, 2026 21:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants